#ifndef MCP2515_H
#define MCP2515_H

#include "spi.h"


// Commands
#define MCP2515_RESET 				(0xC0)
#define MCP2515_READ_STATUS 		(0xA0)
#define MCP2515_READ_RX_STATUS		(0xB0)
#define MCP2515_READ_REGISTER 		(0x03)
#define MCP2515_BIT_MODIFY 			(0x05)
#define MCP2515_WRITE_REGISTER 		(0x02)
#define MCP2515_RTS 				(0x80)
#define MCP2515_LOAD_TX_BUFFER		(0x40)
#define MCP2515_READ_RX_BUFFER		(0x90)

void mcp2515_init(void);
void mcp2515_reset(void);
uint8_t mcp2515_read_status(void);
uint8_t mcp2515_read_rx_status(void);
uint8_t mcp2515_read_register(uint8_t address);
void mcp2515_bit_modify(uint8_t address, uint8_t mask, uint8_t data);
void mcp2515_write_register(uint8_t address, uint8_t data);
void mcp2515_request_to_send(uint8_t buffers);
void mcp2515_load_transmit_buffer(uint8_t buffer, uint8_t identifier, uint8_t* data, uint8_t len);
void mcp2515_read_receive_buffer(uint8_t buffer, uint8_t* identifier, uint8_t* data, uint8_t* len);
void can_transmit_message(uint8_t identifier, uint8_t* data, uint8_t len);
void can_read_message(uint8_t* id, uint8_t* data, uint8_t* len);

void can_message_headlights(uint8_t on_off);
void can_message_directionlights(uint8_t on_off);
void can_message_servo_position(uint8_t servo, uint16_t position);
int16_t can_message_get_temperature(void);

// Control registers
#define MCP2515_CNF1				(0x2A)
#define MCP2515_CNF2				(0x29)
#define MCP2515_CNF3				(0x28)
#define MCP2515_CANCTRL				(0x0F)

// CANCTRL register
#define MCP2515_REQOP_MASK			(0xE0)
#define MCP2515_REQOP				(0x05)
#define MCP2515_NORMAL_MODE			(0x00)
#define MCP2515_CONFIGURATION_MODE	(0x04)	

// Status register bits
#define MCP2515_CANINTF_RX0IF 		(1<<0)
#define MCP2515_CANINTF_RX1IF 		(1<<1)
#define MCP2515_TXB0CNTRL_TXREQ 	(1<<2)
#define MCP2515_CANINTF_TX0IF		(1<<3)
#define MCP2515_TXB1CNTRL_TXREQ		(1<<4)
#define MCP2515_CANINTF_TX1IF		(1<<5)
#define MCP2515_TXB2CNTRL_TXREQ		(1<<6)
#define MCP2515_CANINTF_TX2IF		(1<<7)

// RX Status register bits
#define MCP2515_RXSTATUS_RXB0		(1<<6)
#define MCP2515_RXSTATUS_RXB1		(1<<7)

// Transmit buffers
#define MCP2515_TXREQ_MASK			(0x08)
#define MCP2515_TXREQ				(0x08)

#define MCP2515_TXB0CTRL			(0x30)
#define MCP2515_TXB0SIDH			(0x31)
#define MCP2515_TXB0SIDL			(0x32)
#define MCP2515_TXB0EID8			(0x33)
#define MCP2515_TXB0EID0			(0x34)
#define MCP2515_TXB0DLC				(0x35)
#define MCP2515_TXB0D0				(0x36)	
#define MCP2515_TXB1CTRL			(0x40)
#define MCP2515_TXB1SIDH			(0x41)
#define MCP2515_TXB1SIDL			(0x42)
#define MCP2515_TXB1EID8			(0x43)
#define MCP2515_TXB1EID0			(0x44)
#define MCP2515_TXB1DLC				(0x45)
#define MCP2515_TXB1D0				(0x46)
#define MCP2515_TXB2CTRL			(0x50)
#define MCP2515_TXB2SIDH			(0x51)
#define MCP2515_TXB2SIDL			(0x52)
#define MCP2515_TXB2EID8			(0x53)
#define MCP2515_TXB2EID0			(0x54)
#define MCP2515_TXB2DLC				(0x55)
#define MCP2515_TXB2D0				(0x56)

// CAN MESSAGE DEFINES
#define CAN_MSG_HEADLIGHTS_ID		(0xA1)
#define CAN_MSG_HEADLIGHTS_ON		(0x01)
#define CAN_MSG_HEADLIGHTS_OFF		(0x00)
#define CAN_MSG_DIRLIGHTS_ID		(0xA2)
#define CAN_MSG_DIRLIGHTS_OFF		(0x00)	
#define CAN_MSG_DIRLIGHTS_LEFT		(0x01)
#define CAN_MSG_DIRLIGHTS_RIGHT		(0x02)
#define CAN_MSG_DIRLIGHTS_ON		(0x03)
#define CAN_MSG_SERVO1_POS_ID		(0xB1)
#define CAN_MSG_SERVO2_POS_ID		(0xB2)
#define CAN_MSG_GET_TEMP_ID			(0xA3)
#define CAN_MSG_GET_TEMP_RESPONSE	(0x08)
#endif
